package savet.util.io;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import javax.swing.JFileChooser;
import savet.util.CustomFileChooser;

/**
 * Utilitario para gerar os arquivos do sistema.
 * Para se utilizar este utilitario, deve-se executar primeiramente
 * o {@link ArquivoUtil#criarArquivoUtilInstance(int)}, indicando o tipo de
 * arquivo que sera manipulado pelo sistema.
 *
 * @author Adisson Marinho
 */
public abstract class ArquivoUtil {

    public static final int ARQUIVO_XML = 1;
    public static final int ARQUIVO_BINARIO = 2;
    private static ArquivoUtil instance;
    private static File ultimoArquivoAberto;

    static {
        criarArquivoUtilInstance(ARQUIVO_XML);
    }

    protected ArquivoUtil() {
    }

    /**
     * Baseado nos tipos {@link #ARQUIVO_BINARIO} e {@link #ARQUIVO_XML}.
     * @param tipoArquivo
     */
    public static void criarArquivoUtilInstance(int tipoArquivo) {
        if (tipoArquivo == ARQUIVO_BINARIO) {
            instance = new ObjectOutputStreamUtil();
        } else if (tipoArquivo == ARQUIVO_XML) {
            instance = new XMLArquivoUtil();
        }

    }

    public abstract Serializable abrirArquivo(File file) throws IOException, ClassNotFoundException;

    public abstract void salvarArquivo(File file, Serializable object) throws IOException;

    private static File conferirNomeArquivo(File file) {
        String oldPath = file.getPath();
        System.out.println("oldPath: " + oldPath);
        if (!oldPath.contains(".saud") && !oldPath.contains(".saudita")) {
            StringBuilder newPath = new StringBuilder(oldPath);
            newPath.append(".saud");
            System.out.println("newPath: " + newPath);
            file = new File(newPath.toString());
        }
        return file;
    }

    public static Serializable abrirComFileChooser() throws IOException, ClassNotFoundException {
        File file = carregarFileChooser(JFileChooser.OPEN_DIALOG);
        ultimoArquivoAberto = file;
        return instance.abrirArquivo(file);
    }

    public static void salvarComFileChooser(Serializable object) throws IOException {
        File file = carregarFileChooser(JFileChooser.SAVE_DIALOG);
        if (file != null) {
            instance.salvarArquivo(file, object);
        }
    }

    public static void salvar(File arquivo, Serializable object) throws IOException {
        instance.salvarArquivo(arquivo, object);
    }

    /**
     * Carrega um componente para selecao de arquivos no sistema.
     *
     * @param tipoFileChooser {@link JFileChooser#OPEN_DIALOG} ou {@link JFileChooser#SAVE_DIALOG}
     * @return arquivo selecionado
     * @see JFileChooser
     */
    private static File carregarFileChooser(int tipoFileChooser) {
        File file = null;
        JFileChooser fc = new CustomFileChooser("/");
        int result = JFileChooser.CANCEL_OPTION;

        fc.addChoosableFileFilter(new FiltroSaudita());
        fc.addActionListener(null);

        if (tipoFileChooser == JFileChooser.OPEN_DIALOG) {
            fc.setApproveButtonText("Abrir");
            fc.setDialogTitle("Abrir arquivo...");
            result = fc.showOpenDialog(null);
        } else if (tipoFileChooser == JFileChooser.SAVE_DIALOG) {
            fc.setApproveButtonText("Salvar");
            fc.setDialogTitle("Salvar arquivo...");
            result = fc.showSaveDialog(null);
        }

        if (result == JFileChooser.APPROVE_OPTION) {
            file = conferirNomeArquivo(fc.getSelectedFile());
        }
        return file;
    }

    public static ArquivoUtil getInstance() {
        return instance;
    }

    public static File getUltimoArquivoAberto() {
        return ultimoArquivoAberto;
    }
}
